/*
 * $Id: main.cpp,v 1.8 2005/02/16 10:45:39 tsuruoka Exp $
 */

#include <stdio.h>
#include <fstream>
#include <map>
#include <list>
#include <iostream>
#include <sstream>
#include "maxent.h"
#include "common.h"
#include "article.h"
using namespace std;



ME_Model Train_NER2(string path,vector<ME_Model> vme,vector<ME_Model> vme_chunking);
string bidir_postag(const string & s, const vector<ME_Model> & vme, const vector<ME_Model> & cvme, bool dont_tokenize);
void bidir_chunking(vector<Sentence> & vs, const vector<ME_Model> & vme);
void init_morphdic();
void help()
{
	cout << "Usage: geniatagger [OPTION]... [FILE]..." << endl;
	cout << "Analyze English sentences and print the base forms, part-of-speech tags, " << endl;
	cout << "chunk tags, and named entity tags." << endl;
	cout << endl;
	cout << "Options:" << endl;
	cout << "  --help\t\tdisplay this help and exit." << endl;
	cout << "  --p <input folder> <outputfolder>display this help and exit." << endl;
	cout << endl;
	cout << "Report bugs to <tsuruoka@is.s.u-tokyo.ac.jp>." << endl;
	cout << "Report bugs to <mostafa.shokrof@gmail.com>." << endl;
}

void version()
{
	cout << "GENIA Tagger 4.0" << endl << endl;
}

extern void load_ne_models();
vector<ME_Model> vme(16);
vector<ME_Model> vme_chunking(16);
ME_Model MoleculerNES,DiseasesNES;
ME_Model ContainRelation,Classify;

void LoadPOS_ChunkingMOdels()
{
	init_morphdic();
	cerr << "loading pos_models";
	for (int i = 0; i < 16; i++) {
		char buf[1000];
		sprintf(buf, "./models_medline/model.bidir.%d", i);
		vme[i].load_from_file(buf);
		cerr << ".";
	}
	cerr << "done." << endl;
	cerr << "loading chunk_models";
	for (int i = 0; i < 8; i +=2 ) {
		char buf[1000];
		sprintf(buf, "./models_chunking/model.bidir.%d", i);
		vme_chunking[i].load_from_file(buf);
		cerr << ".";
	}
	cerr << "done." << endl;

}
void tokenize(const string & s1, list<string> & lt);
extern void load_word_info(const string & filename);
void loadNEmodels()
{
	load_word_info("./models_named_entity/word_info");
	MoleculerNES.load_from_file("./models_named_entity/model001");
	DiseasesNES.load_from_file("./models_named_entity/DiseaseModel");
}
void loadrelationsmodels()
{
	Classify.load_from_file("models_relations/Classifier");
	ContainRelation.load_from_file("models_relations/Found_OR_Not");
}
int main(int argc, char** argv)
{
	istream *is(&std::cin);
	string ifilename, ofilename;
	if(argc==1){help(); exit(0);}
	string v = argv[1];
	if (v == "--help") { help(); exit(0); }
	else if(v =="--freetext")
	{
		LoadPOS_ChunkingMOdels();
		load_ne_models();
		string line;
		int n = 1;
		while (getline(*is, line)) {
			if (line.size() > 1024) {
				cerr << "warning: the sentence seems to be too long at line " << n;
				cerr << " (please note that the input should be one-sentence-per-line)." << endl;
			}
			string postagged = bidir_postag(line, vme, vme_chunking, false);
			cout << postagged << endl;

			n++;
		}
	}
	else if(v =="--p")
	{
		LoadPOS_ChunkingMOdels();
		loadNEmodels();
		loadrelationsmodels();
		string inputpath=argv[2];
		string outpath=argv[3];

		string temp=getStdoutFromCommand("ls "+inputpath);
		vector<string> paperpathes;
		split(temp,"\n",&paperpathes);
		//cout<<"heloo"<<endl;
		for(int i=0;i<paperpathes.size();i++)
		{
			article * a=new article();
			a->readfromPubmedxml(inputpath+paperpathes[i]);
			a->NLPProcessing(vme,vme_chunking,MoleculerNES);
			a->NLPProcessing(vme,vme_chunking,DiseasesNES);
			a->getNamed_entities();
			vector<Relation> relations;
			relations.clear();
			relations=a->getRealtions(ContainRelation,Classify);
			Relation R;
			if(relations.size()>0)
				R.writetoHTML(relations,outpath+"Relations"+paperpathes[i]);
			a->writetoHTML(outpath);
			delete a;
		}
	}
	else if(v =="--t")
	{
		LoadPOS_ChunkingMOdels();
		load_word_info("./models_named_entity/word_info");
		ME_Model M=Train_NER2(argv[2],vme,vme_chunking);
		M.save_to_file(argv[3]);
	}
	else if(v=="-R")
	{
		ifstream ReadFile;
		string line;
		vector<string> Sentences;
		vector<string> res;
		vector<string> dis;
		vector<string> my_dis;
		vector<Relation*> relations;
		string Inpath=argv[2];
		ReadFile.open(Inpath.c_str());
		if (!ReadFile.is_open())
		{
			cout<<"Can not open the file"<<endl;
		}
		while (!ReadFile.eof())
		{
			getline(ReadFile,line);
			if(line!="")
			{
				Sentences.clear();
				dis.clear();
				my_dis.clear();
				string sss;
				//	cout<<"\nThis is the whole line \n"<<line<<endl;
				split(line,"||",&Sentences);
				//cout<<"\n This is the asdas \n"<<Sentences.front()<<endl;
				//Sentences.push_back(Sentences.front());
				//	s.features.size()cout<<"\nsen-->"<<Sentences.at(0)<<" "<<Sentences[1]<<endl;
				if (Sentences[1].compare("NONE")!=0&&Sentences[1].compare("TO_SEE")!=0&&Sentences[1].compare("DISONLY")!=0&&Sentences[1].compare("TREATONLY")!=0)
				{
					cout<<"in "<<Sentences[1]<<endl;
					list<string> tokens;
					tokens.clear();
					Sentence * s1=new Sentence();
					tokenize(Sentences[0],tokens);
					string disease[12]={"DISONLY","DIS","DIS_NO","DIS_SIDE_EFF","DIS_PREV","DIS_VAG","/DISONLY","/DIS_NO","/DIS","/DIS_SIDE_EFF","/DIS_PREV","/DIS_VAG"};
					string treat[12]={"TREATONLY","TREAT_NO","/TREAT_NO","TREAT","TREAT_SIDE_EFF","TREAT_PREV","TREAT_VAG","/TREATONLY","/TREAT","/TREAT_SIDE_EFF","/TREAT_PREV","/TREAT_VAG"};
					bool intag=false;
					string currenttag="";
					vector<int> begin;
					vector<int> end;
					vector<string> ne;
					begin.clear();
					end.clear();
					ne.clear();
					int count=0;
					for(list<string>::iterator it=tokens.begin();it!=tokens.end();it++,count++)
					{
						string temp=*it;

						if(temp.compare("<")==0||temp.compare(">")==0)
							continue;
						for(int i=0;i<12;i++)
							if(it->compare(disease[i])==0)
							{
								//			cout<<temp<<endl;
								temp="DISEASE";
								break;
							}
						for(int i=0;i<12;i++)
							if(it->compare(treat[i])==0)
							{
								//		cout<<temp<<endl;
								temp="TREAT";
								break;
							}


						if(!intag)
						{
							if(temp.compare("DISEASE")==0||temp.compare("TREAT")==0)//begin
							{
								begin.push_back(count);
								cout<<"flag "<<count<<endl;
								ne.push_back(temp);
								currenttag=temp;
								intag=true;
							}
							else
							{
								s1->push_back(Token(temp,""));
							}
						}
						else
						{
							if(temp.compare("DISEASE")==0||temp.compare("TREAT")==0)//end
							{
								end.push_back(count);
								intag=false;
							}
							else
							{
								Token t=Token(temp,"");
								t.ne=currenttag;
								s1->push_back(t);
							}
						}
					}
					Relation * r=new Relation();
					r->my_sentences=s1;
					r->relation_type=Sentences[1];
					cout<<"\t "<<ne.size()<<endl;
					if(ne.size()==0)
						cout<<"a7a meen deih "<<s1->at(0).str<<" "<<s1->at(1).str<<endl;
					if(ne.at(0).compare("DISEASE")==0)
					{
						r->begin_entity1=begin[1];
						r->end_entity1=end[1];
						r->name_entity_type_1=ne[1];
						r->begin_entity2=begin[0];
						r->end_entity2=end[0];
						r->name_entity_type_2=ne[0];
					}
					else
					{
						r->begin_entity1=begin[0];
						r->end_entity1=end[0];
						r->name_entity_type_1=ne[0];
						r->begin_entity2=begin[1];
						r->end_entity2=end[1];
						r->name_entity_type_1=ne[1];
					}
					relations.push_back(r);

				}
				else if (Sentences[1].compare("NONE")==0)
				{
					//		cout<<Sentences[0]<<endl;
				}
			}
		}
		vector<Relation> train;
		vector<Relation> test;
		for(int i=0;i<relations.size();i++)
		{
			if(i%5==0)
				test.push_back(*relations[i]);
			else
				train.push_back(*relations[i]);
		}
		cout<<"train size"<<train.size()<<endl;
		cout<<"test size"<<test.size()<<endl;
		Relation rr;
		rr.write_to_XML("test/train",train);
		rr.write_to_XML("test/test",test);
		ReadFile.close();
	}


	return 0;
}


